<?php

namespace App\Morefun\Quiz;

use App\Contracts\Repositories\QuizRepository as QuizRepositoryContract;
use App\Entities\Quiz;
use App\Entities\QuizOption;

class QuizService
{
    protected $quizzes;

    public function __construct(QuizRepositoryContract $quizzes)
    {
        $this->quizzes = $quizzes;
    }

    public function unlinked($activityId, $without = null)
    {
        $wheres[] = ['activity_id', '=', $activityId];
        $wheres[] = ['type', '!=', Quiz::TYPE_FILL_BLANK];

        if ($without) {
            $withoutQuiz = $this->quizzes->find($without, ['created_at']);

            if ($withoutQuiz !== null) {
                $wheres[] = ['id', '!=', $without];
                $wheres[] = ['created_at', '<', $withoutQuiz->created_at];
            }
        }

        return $this->quizzes->findAll($wheres, ['id', 'title']);
    }

    public function findWithPaginate($perPage, $keyword, array $columns)
    {
        $buildWheres = function ($keyword, array $columns) {
            $wheres = [];

            if ($keyword) {
                $wheres[] = ['title', 'LIKE', '%' . $keyword . '%'];
            }
            $columns = array_filter($columns);
            foreach ($columns as $column => $value) {
                $wheres[] = [$column, '=', $value];
            }

            return $wheres;
        };

        return Quiz::withOptions()
            ->where($buildWheres($keyword, $columns))
            ->orderBy('created_at', 'ASC')
            ->paginate($perPage);
    }

    public function findQuizResult($activityId, $page = 1, $limit = 0)
    {
        return $this->quizzes->findQuizResult($activityId, $page, $limit);
    }

    public function formatQuizResult($activityId)
    {
        $data = [];
        $quizzes = Quiz::query()
            ->where('activity_id', $activityId)
            ->whereNull('deleted_at')
            ->get();
        $qNumber = $quizzes->count();
        if ($qNumber > 0) {
            $rowData = [];
            $optionData = $this->getQuizOptions($quizzes);
            $quizResult = $this->findQuizResult($activityId);
            $openids = [];
            if ($quizResult->count() > 0) {
                $unique = '';
                foreach ($quizResult as $item) {
                    $tmp = $item->nickname . '-' . $item->mobile . '-' . $item->openid;
                    if ($unique == '' || $unique != $tmp) {
                        $unique = $tmp;
                        if (!empty($rowData)) {
                            $data[] = $rowData;
                            $rowData = [];
                        }
                        $rowData['提交人'] = $item->nickname;
                        $rowData['手机号'] = $item->mobile;
                        $rowData['OpenId'] = $item->openid;
                        $rowData['提交时间'] = $item->created_at;
                    }
                    $rowData = $this->formatResult($item, $optionData, $rowData, $quizzes);
                }
            }
            if (!empty($rowData) && !in_array($rowData['OpenId'], $openids)) {
                $data[] = $rowData;
                $openids[] = $rowData['OpenId'];
            }
        }

        return $data;
    }

    private function formatResult($quizSheet, $optionData, $rowData, $quizzes)
    {
        if ($quizSheet->type == Quiz::TYPE_CHOICE_SINGLE || $quizSheet->type == Quiz::TYPE_CHOICE_MULTI) {
            $json = \GuzzleHttp\json_decode($quizSheet->option_id);
            $str = '';
            foreach ($json as $option) {
                $val = '';
                if (isset($optionData[$quizSheet->id]) && isset($optionData[$quizSheet->id][$option])) {
                    $val = $optionData[$quizSheet->id][$option];
                }
                $str .= $val . ' ';
            }
            $rowData[$quizSheet->title] = $str;
            $rowData = $this->fillQuizDefaultValue($quizzes, $rowData);
        }
        if ($quizSheet->type == Quiz::TYPE_FILL_BLANK) {
            $json = \GuzzleHttp\json_decode($quizSheet->fill_content);
            $rowData[$quizSheet->title] = $json[0];
        }

        return $rowData;
    }

    private function getQuizOptions($quizzes)
    {
        $optionData = [];
        $quizIds = [];
        if ($quizzes->count()) {
            foreach ($quizzes as $quiz) {
                $quizIds[] = $quiz->id;
            }
        }
        $options = QuizOption::query()
            ->whereIn('quiz_id', $quizIds)
            ->get();
        if ($options) {
            foreach ($options as $option) {
                if (!isset($optionData[$option->quiz_id])) {
                    $optionData[$option->quiz_id] = [];
                }
                $optionData[$option->quiz_id][$option->id] = $option->text;
            }
        }

        return $optionData;
    }

    private function fillQuizDefaultValue($quizzes, $exportRowData)
    {
        if (!$quizzes->count()) {
            return $exportRowData;
        }
        foreach ($quizzes as $quiz) {
            if(!isset($exportRowData[$quiz->title])){
                $exportRowData[$quiz->title] = '';
            }
        }

        return $exportRowData;
    }

}
